#!/usr/bin/env python

import Numeric as N
import pygamesvg
import pygame
from pygame.locals import *

import debug
import helper
from debug import *
from helper import *

def svg_filename_to_surface(fn, *args, **properties):
  return svg_file_to_surface(file(fn), *args, **properties)

def svg_file_to_surface(fh, *args, **properties):
  return svg_to_surface(fh.read(), *args, **properties)

def svg_to_surface(svg_data, size=(0, 0), scale=(1.0, 1.0), alpha=1.0):
  return pygamesvg.toSurface(svg_data, size, scale, alpha).convert_alpha()

def change_svg_color(svg_data, *args):
  new_data = svg_data
  for a in args:
    old_color, new_color = a
    new_data = new_data.replace(old_color, new_color)
  return new_data

def rgb_tuple_to_hex(rgb):
  return rgb_to_hex(rgb[0], rgb[1], rgb[2])

def rgb_to_hex(r, g, b):
  if r > 255: r = 255
  elif r < 0: r = 0
  if g > 255: g = 255
  elif g < 0: g = 0
  if b > 255: b = 255
  elif b < 0: b = 0
  return '%x%x%x' % (r, g, b)

def hex_to_rgb(hex):
  if hex[0] == '#': hex = hex[1:]
  return (int(hex[0:2], 16), int(hex[2:4], 16), int(hex[4:6], 16))


class Animation:
  def __init__(self, *args, **properties):
    self.frames = get_prop(properties, 'frames', 1)
    self.curr_frame = 0
    self.frame_list = []
  
  def get_frame_list(self):
    return self.frame_list
  
  def get_frame(self, i):
    return self.frame_list[i]
  
  def get_last_frame(self):
    return self.get_frame(len(self.frame_list) - 1)
  
  def update(self, frame=None):
    if frame is not None and frame >= 0 and frame < len(self.frame_list):
      return self.frame_list[frame]
    
    if self.curr_frame < self.frames - 1:
      self.curr_frame += 1
    else:
      self.curr_frame = 0
    return self.frame_list[self.curr_frame]

class Still(Animation):
  def __init__(self, surf):
    Animation.__init__(self, frames=1)
    #self.surface = surf
    self.frame_list.append(surf)
  '''
  def update(self, frame=None):
    return self.surface
  '''
class Grayscale(Still):
  def __init__(self, surf):
    Still.__init__(self, surf)
    surface = self.rgb_to_grayscale(surf)
    self.frame_list = [surface]
  
  def rgb_to_grayscale(self, surface):
    info('Surface bitsize: %d' % (surface.get_bitsize()))
    rgbarr = pygame.surfarray.pixels3d(surface)
    #print type(rgbarr)
    
    orig = N.array(rgbarr)
    grayscale = N.array(rgbarr)
    
    grayscale[:,:,0] = orig[:,:,0] / 10 * 3 + orig[:,:,1] / 10 * 5.9 + orig[:,:,2] / 10 * 1.1
    grayscale[:,:,1] = orig[:,:,0] / 10 * 3 + orig[:,:,1] / 10 * 5.9 + orig[:,:,2] / 10 * 1.1
    grayscale[:,:,2] = orig[:,:,0] / 10 * 3 + orig[:,:,1] / 10 * 5.9 + orig[:,:,2] / 10 * 1.1
    
    new_surf = pygame.surfarray.make_surface(grayscale).convert_alpha(surface)
    new_surf_arr = pygame.surfarray.pixels_alpha(new_surf)
    new_surf_arr[:, :] = pygame.surfarray.pixels_alpha(surface)[:, :]
    
    surface.unlock()
    new_surf.unlock()
    
    return new_surf
  

class SmoothZoom(Animation):
  def __init__(self, svg_fn, frames=30, start=(1.0, 1.0), stop=(0.5, 0.5)):
    Animation.__init__(self, frames)
    self.init_scale_list(svg_fn, start, stop)
  
  def init_scale_list(self, svg_fn, start_sc, stop_sc):
    svg_data = file(svg_fn).read()
    start_sc_x, start_sc_y = start_sc
    stop_sc_x,  stop_sc_y  = stop_sc
    
    frames = float(self.frames)
    #we don't have smoothscale, so use pygamesvg's scaling ability instead
    for i in range(0, self.frames):
      
      curr_sc = (start_sc_x + i * (stop_sc_x - start_sc_x) / frames,
                 start_sc_y + i * (stop_sc_y - start_sc_y) / frames,
                )
      self.frame_list.append(svg_to_surface(svg_data, scale=curr_sc))

class SmoothAlpha(Animation):
  def __init__(self, svg_fn, start=1.0, stop=0.5, *args, **properties):
    Animation.__init__(self, *args, **properties)
    scale = get_prop(properties, 'scale', (1.0, 1.0))
    size = get_prop(properties, 'size', (0, 0))
    self.init_blink_list(svg_fn, start, stop, scale, size)
  
  def init_blink_list(self, svg_fn, start_al, stop_al, sc, sz):
    svg_data = file(svg_fn).read()
    
    frames = float(self.frames)
    #we don't have smoothscale, so use pygamesvg's scaling ability instead
    for i in range(0, self.frames):
      
      curr_al = start_al + i * (stop_al - start_al) / frames
      self.frame_list.append(svg_to_surface(svg_data, alpha=curr_al, scale=sc, size=sz))

def Custom(Animation):
  def __init__(self, *args):
    self.loop = True
    for i in range(0, len(args)):
      a = args[i]
      if len(a) == 2:
        anim, gap_frames = a
      else:
        anim = a[0]
        gap_frames = 0
        if i == len(args) - 1:
          self.loop = False
      self.frame_list.extend(anim.get_frame_list())
      last_frame = anim.get_last_frame()
      
      g_f = [last_frame] * gap_frames
      self.frame_list.extend(g_f)
  '''
  def update(self):
    if self.curr_frame < self.frames - 1:
      self.curr_frame += 1
    else:
      if self.loop:
        self.curr_frame = 0
    return self.frame_list[self.curr_frame]
  '''
